/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "主窗口.h"

#include <file_文件名数据.h>
//#include <几何图形/几何模型生成.h>

#include "core/时间.h"

#include "A_引擎/引擎.h"
#include "A_引擎/文件工程/工程文件.h"
#include "A_引擎/文件工程/配置.h"

#include "B_场景管理/操作记录.h"
#include "物体管理/渲染物体创建销毁.h"

#include "框架/ui组件构建结构.h"
#include "框架/屏幕.h"

#include "框架/工作区/时间轴视口/时间轴视口工作区.h"
#include "框架/照壁界面/照壁主界面.h"

#include "渲染/渲染.h"
#include "框架/菜单管理.h"

 
#include <系统/系统平台.h>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <string>
#include <core/引擎配置.h>
#include <core/设备内存缓存.h>
#include <Input/Input.h>
#include <MBT_Engine.h>
#include <UI/UI.h>
#include <UI/UI主题.h>
#include <UI/Widget.h>
#include <场景/场景.h>
#include <底层绘图/底层绘图框架.h>
#include <引擎数据类型.h>
#include <引擎枚举数据.h>
#include <窗口/窗口.h>
#include <纹理/纹理.h>
#include <缓存.h>
#include <面/Surface.h>
#include <面/面.h>
#include <basic_def.h>
#include "框架/工作区/ui属性栏.h"

#include <节点全局数据.h>





//S_Window* window = 0;
//S_Window* window_temp = 0;

static C_Widget* gui节点视口工作区 = 0;
static C_Widget* ui_实验组件 = 0;



void f_实验组件更新() {
	//f_ui_set行文本框文本(ui_实验组件, f_浮点数值转宽字符串(window->m_帧数));
}


static E_事件是否传递 on_保存工程(C_Widget* self, E_键位执行状态 状态) {
	if (f_projectFile_保存当前文件() == false) {
		f_ui_打开对话框(S_框架::g_文件窗口, E_对话框类型::e_写入, on_projectFile_文件打开保存, "I:/TEMP/", u".np");
	}

	f_projectFile_设置文件保存状态(true);
	return E_事件是否传递::e_事件传递_终止;
}


static E_事件是否传递 on_打开工程(C_Widget* self, E_键位执行状态 状态) {
	if (f_projectFile_保存当前文件() == false) {
		f_ui_打开对话框(S_框架::g_文件窗口, E_对话框类型::e_读取, on_projectFile_文件打开保存, "I:/TEMP/", u".np");
	}
	return E_事件是否传递::e_事件传递_终止;
}




static void on_GPU参数修改更新渲染器(struct S_板载缓存* buf) {
	f_render_刷新渲染(f_NodeCtx_get默认场景());
}



void f_init主窗口() {
	std::wstring 新环境变量 = S_引擎配置::g_程序路径.wstring() + L"cxxlib";
	
	std::wstring 已有环境变量 = _wgetenv(L"PATH");
	新环境变量 += L";" + 已有环境变量;
	_wputenv_s(L"PATH", 新环境变量.c_str());

	DEF_记录日志("初始化环境变量");


#ifdef 预定义_最终输出
	
#else
	
#endif // 预定义_最终输出


	S_UI主题::ui_默认字体 = u"雅黑";
	//S_引擎配置::f_初始化着色器文件路径();
	S_节点数据::g_编译器路径 = (S_引擎配置::g_程序路径 / "compiled").generic_string();
	
	
	//S_节点框架::g_3D视口环境 = f_df_创建渲染环境(S_节点框架::ctx, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理格式::e_tf_D32F, E_MS次数::e_MS_1);
	//S_节点框架::g_UI视口环境 = f_df_创建渲染环境(S_节点框架::ctx, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理格式::e_tf_D32F, E_MS次数::e_MS_1);
	DEF_记录日志("创建图形运行环境");


	//S_框架::engine->m_绘图框架->m_Ctx = *S_节点框架::g_3D视口环境;
	
	f_engine_创建3D缓存(*S_节点框架::g_3D视口环境, true); DEF_记录日志("创建3D缓存");
	f_engine_创建2D缓存(*S_节点框架::g_UI视口环境, true); DEF_记录日志("创建2D缓存");
	f_NodeCtx_set默认场景(f_scene_创建(*S_节点框架::g_3D视口环境, 0));
	DEF_记录日志("创建默认场景");


	f_surface_加载矢量图标(*S_节点框架::g_UI视口环境, S_引擎配置::g_程序路径 / "图标资源/矢量图标");
	f_surface_加载矢量图像(*S_节点框架::g_UI视口环境, S_引擎配置::g_程序路径 / "照壁/矢量画心", E_三角形分割方式::e_分割方式_扫描);
	DEF_记录日志("加载图标");


	S_字体加载参数 字体加载参数;
	字体加载参数.m_字体文件路径 = f_sys_get字体文件目录().string() + "/msyh.ttc";
	f_surface_加载矢量字体(*S_节点框架::g_UI视口环境, 字体加载参数, u"雅黑");
	DEF_记录日志("加载字体");

	



	//window = S_框架::f_创建窗口到列队({ 1024, 576 });
	

	if (S_节点框架::g_3D视口环境->m_支持光追) {
		std::cout << "open ray" << std::endl;
		f_scene_开启光追(f_NodeCtx_get默认场景(), *S_节点框架::g_3D视口环境);
		DEF_记录日志("创建光追环境");
	}
	
	
	

	
	std::cout << "init UI" << std::endl;
	std::string 资源加载路径 = S_引擎配置::g_程序路径.string();
	std::string 鸿雷板书简体;
	

	S_框架::m_库默认路径 = S_引擎配置::g_程序路径 / "扩展/";
	f_file_创建目录(S_框架::m_库默认路径.string() + "节点模块/");
	f_file_创建目录(S_框架::m_库默认路径.string() + "插件模块/");
	std::cout << "load ico" << std::endl;
	
	
	//============================= 数据初始化 ============================
	S_框架::f_初始化预设资源(*S_节点框架::g_3D视口环境);
	DEF_记录日志("初始化节点环境");

	f_projectFile_设置工程目录(u"");

	f_属性栏_初始化();


	auto* window = f_界面_创建工作窗口(true);
	S_节点框架::g_UIGM = f_window_getUI管理(window);


	S_框架::g_界面构建   = new S_组件构建();
	S_框架::g_ui顶层画布 = f_ui_创建全屏画布(*f_window_getUI环境(window), S_节点框架::g_UIGM);
	S_框架::g_ui顶层画布->m_拾取 = false;
	S_框架::g_ui顶层画布->m_WName = u"顶层画布";

	///S_框架::g_界面图像元素 = f_纹理集_创建();



	f_屏幕_初始化工作区(*f_window_getUI环境(window));
	

	
	f_buf_getGlobal().m_I32动态属性->m_Update = on_GPU参数修改更新渲染器;
	f_buf_getGlobal().m_F32动态属性->m_Update = on_GPU参数修改更新渲染器;
	f_buf_getGlobal().m_Vec2动态属性->m_Update = on_GPU参数修改更新渲染器;
	f_buf_getGlobal().m_Vec3动态属性->m_Update = on_GPU参数修改更新渲染器;
	f_buf_getGlobal().m_全局绑定参数指针->m_Update = on_GPU参数修改更新渲染器;

	
	S_框架::g_节点框架.g_UIGM->mf_输入执行后回调 = f_屏幕_更新工作区;
	
	
	
	{
		//auto ui主菜单 = f_界面构建_主菜单创建(*f_window_getUI环境(window));
		//ui_root->f_添加子组件(ui主菜单);
		//f_ui_set渲染层(ui主菜单);
	}

	{
		/*auto w1 = new C_Widget(f_window_getUI环境(window));
		auto w2 = new C_Widget(f_window_getUI环境(window));
		auto w3 = new C_Widget(f_window_getUI环境(window));
		auto w4 = new C_Widget(f_window_getUI环境(window));

		w1->m_WName = u"text ui w1";
		w2->m_WName = u"text ui w2";

		auto* 屏幕左 = f_屏幕_创建工作区(*f_window_getUI环境(window));
		auto* 屏幕右 = f_屏幕_创建工作区(*f_window_getUI环境(window));
		{
			auto* ui工作区_场景视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_3D视口);
			auto* ui工作区_2D视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_2D视口);

			auto* ui工作区_大纲视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_大纲视口);
			auto* ui工作区_模块视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_终端视口);

			f_屏幕_添加工作区页面(屏幕左, ui工作区_场景视口);
			f_屏幕_添加工作区页面(屏幕左, ui工作区_2D视口);

			f_屏幕_添加工作区页面(屏幕右, ui工作区_大纲视口);
			f_屏幕_添加工作区页面(屏幕右, ui工作区_模块视口);
		}
		

		auto* 屏幕节点区 = f_屏幕_创建工作区(*f_window_getUI环境(window));
		auto* 屏幕时间线 = f_屏幕_创建工作区(*f_window_getUI环境(window));
		{
			{
				auto* ui工作区_节点视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_节点视口);
				f_屏幕_添加工作区页面(屏幕节点区, ui工作区_节点视口);
			}
			{
				auto* ui工作区_时间视口 = f_屏幕_create工作区页面(*f_window_getUI环境(window), E_工作区类型::e_时间轴);
				f_屏幕_添加工作区页面(屏幕时间线, ui工作区_时间视口);
			}
		}
		//auto* ui上分割框 = f_ui_创建分割框({ 屏幕左 , 屏幕右 }, E_方向::e_纵向, { 0.7f, 1.0f }, *f_window_getUI环境(window));
		

		{
			auto* ui上下分割框 = f_ui_创建分割框( { 
				
				f_ui_创建分割框({ 屏幕左 , 屏幕右 }, E_方向::e_纵向, { 0.7f, 1.0f }, *f_window_getUI环境(window)) ,
				屏幕节点区,
				屏幕时间线
			}, E_方向::e_横向, { 0.5f, 0.9f, 1.0f }, * f_window_getUI环境(window));
			
			ui上下分割框->m_是否延展 = { true, true };
			ui_root->f_添加子组件(ui上下分割框);

		}*/

		//f_界面_创建默认工作区(ui_root, window);
	}
	DEF_记录日志("构建界面");
	
	


	//============= 注册快捷键 =================
	S_键盘键位映射* 全局快捷键 = f_widget_init_键盘位映射();
	
	全局快捷键->event = f_操作记录_全局撤销;
	全局快捷键->键盘按键[0] = S_InputKey::e_KEY_左CTRL;
	全局快捷键->键盘按键[3] = S_InputKey::e_KEY_Z;
	全局快捷键->键盘状态[0] = DEF_按键状态_按下中;
	全局快捷键->键盘状态[3] = DEF_按键状态_放开;
	C_键位映射配置::f_添加全局操作键位((S_键位映射*)全局快捷键, u"撤销操作");
	f_ui_注册全局快捷键(*全局快捷键);

	全局快捷键 = f_widget_init_键盘位映射();
	全局快捷键->event = f_操作记录_全局重做;
	全局快捷键->键盘按键[0] = S_InputKey::e_KEY_左CTRL;
	全局快捷键->键盘按键[1] = S_InputKey::e_KEY_左SHIFT;
	全局快捷键->键盘按键[3] = S_InputKey::e_KEY_Z;
	全局快捷键->键盘状态[0] = DEF_按键状态_按下中;
	全局快捷键->键盘状态[1] = DEF_按键状态_按下中;
	全局快捷键->键盘状态[3] = DEF_按键状态_放开;
	C_键位映射配置::f_添加全局操作键位((S_键位映射*)全局快捷键, u"重做操作");
	f_ui_注册全局快捷键(*全局快捷键);

	全局快捷键 = f_widget_init_键盘位映射();
	全局快捷键->event = on_保存工程;
	全局快捷键->键盘按键[0] = S_InputKey::e_KEY_左CTRL;
	全局快捷键->键盘按键[3] = S_InputKey::e_KEY_S;
	全局快捷键->键盘状态[0] = DEF_按键状态_按下中;
	全局快捷键->键盘状态[3] = DEF_按键状态_按下;
	C_键位映射配置::f_添加全局操作键位((S_键位映射*)全局快捷键, u"保存文件");
	f_ui_注册全局快捷键(*全局快捷键);
	
	全局快捷键 = f_widget_init_键盘位映射();
	全局快捷键->event = on_打开工程;
	全局快捷键->键盘按键[0] = S_InputKey::e_KEY_左CTRL;
	全局快捷键->键盘按键[3] = S_InputKey::e_KEY_O;
	全局快捷键->键盘状态[0] = DEF_按键状态_按下中;
	全局快捷键->键盘状态[3] = DEF_按键状态_按下;
	C_键位映射配置::f_添加全局操作键位((S_键位映射*)全局快捷键, u"打开文件");
	f_ui_注册全局快捷键(*全局快捷键);




	S_鼠标键位映射* 全局鼠标键位 = f_widget_init_鼠标键位映射();
	全局鼠标键位->event = f_工作区_时间帧步进;
	全局鼠标键位->键盘按键[0] = S_InputKey::e_KEY_左ALT;
	全局鼠标键位->键盘状态[0] = DEF_按键状态_按下中;
	全局鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	全局鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	C_键位映射配置::f_添加全局操作键位((S_键位映射*)全局鼠标键位, u"步进时间帧");
	f_ui_注册全局鼠标快捷键(*全局鼠标键位);


	S_引擎配置::g_当前加载文件版本号 = S_引擎配置::g_文件版本号;



	f_菜单管理_创建();
	DEF_记录日志("菜单创建");

	//f_照壁_初始化(*f_window_getUI环境(window));
	f_projectFile_加载扩展库();


	//std::string 默认路径 = "I:/TEMP/";
	//if (f_file_文件是否存在(默认路径) == false) {
	//	默认路径 = f_str_u16_to_u8(S_引擎配置::g_工程文件临时路径);
	//}
	//S_框架::g_文件窗口 = S_框架::f_创建窗口到列队({ 640, 420 }, false);
	//S_框架::g_ui文件对话框 = f_ui_创建文件对话框(*f_window_getUI环境(S_框架::g_文件窗口), 默认路径);
	//
	//std::filesystem::path 最近打开文件 = S_引擎配置::g_配置文件路径;
	//最近打开文件 += "/MBT3D/最近打开文件.txt";
	//FILE* f = fopen(最近打开文件.string().c_str(), "rb");
	//if (f) {
	//	S_框架::g_最近打开文件 = f_file_读取字符串组(f);
	//	fclose(f);
	//}
	//f_ui_添加临时文件路径(S_框架::g_ui文件对话框, S_框架::g_最近打开文件);
	//f_window_安装UI(S_框架::g_文件窗口, S_框架::g_ui文件对话框);

	S_框架::g_文件窗口 = f_界面_创建文件对话框();


	S_框架::g_ui_帮助弹出窗口 = f_ui_创建弹出消息框(*f_window_getUI环境(window));
	S_框架::g_ui_加载保存信息框 = f_ui_创建加载保存信息框(*f_window_getUI环境(window), 10);
	DEF_记录日志("对话框创建");
	

	

}


void f_run主循环() {

	//const int size = 1000000;
	//std::vector<int> numbers(size);
	//for (int i = 0; i < size; ++i) {
	//	numbers[i] = i;
	//}
	//
	//// 使用 Lambda 表达式
	//auto start = std::chrono::high_resolution_clock::now();
	//auto f = [&](int x) { 
	//	float64 a = 434532.123454;
	//	float64 b = 434532.123454;
	//	static float64 c = 78615.38;
	//	for (uint32 i = 0; i < 1000; ++i) {
	//		a /= b;
	//		a += b/c;
	//	}
	//	return x * x / a;
	//};
	//applyFunction(numbers, f);
	//auto end = std::chrono::high_resolution_clock::now();
	//auto lambda_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
	//
	//// 重置向量元素
	//for (int i = 0; i < size; ++i) {
	//	numbers[i] = i;
	//}
	//
	//// 使用函数指针
	//int (*func_ptr)(int) = square;
	//start = std::chrono::high_resolution_clock::now();
	//for (int& num : numbers) {
	//	num = func_ptr(num);
	//}
	//end = std::chrono::high_resolution_clock::now();
	//auto func_ptr_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
	//
	//std::cout << "Lambda 表达式耗时: " << lambda_duration << " 微秒" << std::endl;
	//std::cout << "函数指针调用耗时: " << func_ptr_duration << " 微秒" << std::endl;
	


	f_projectFile_设置文件保存状态(false);
	
	S_框架::f_刷新窗口();
	//f_照壁_打开();
	//static C_计时 UI合成计时(60, "主循环");

	bool quit = true;
	
	while (quit) {
		quit = false;

		//UI合成计时.begin();
		S_框架::f_刷新窗口();
		
		f_屏幕_更新工作区();

		bool 暂停 = S_框架::g_资源加载保存.f_轮询事件();
		if (暂停) {
			f_window_触发消息(S_框架::g_主窗口.data(), S_框架::g_主窗口.size());
		}
		//f_window_等待();
		f_window_轮询(S_框架::g_主窗口.data(), S_框架::g_主窗口.size(), quit, 暂停);
		
		
		//UI合成计时.end();
	}

}

void f_close主窗口() {
	f_ui_销毁全屏画布(S_框架::g_ui顶层画布);
	f_surface_卸载矢量字体(*S_节点框架::g_UI视口环境, u"雅黑");


	f_菜单管理_销毁();
	f_属性栏_清理();

	f_屏幕_清理工作区();


	S_框架::f_销毁列队窗口();
	f_render_关闭渲染器();
}














